#include <iostream>
#include <memory>
#include <string>

class Fruit
{
public:
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    void name() override
    {
        std::cout << "我是一个苹果" << std::endl;
    }
};

class Banana : public Fruit
{
public:
    void name() override
    {
        std::cout << "我是一个香蕉" << std::endl;
    }
};

class Animal
{
public:
    virtual void name() = 0;
};

class Dog : public Animal
{
public:
    void name() override
    {
        std::cout << "我是一个小狗" << std::endl;
    }
};

class Cat : public Animal
{
public:
    void name() override
    {
        std::cout << "我是一个小猫" << std::endl;
    }
};

// 简单工厂模式
// class Factory
//{
// public:
//    static std::shared_ptr<Fruit> create(const std::string &name)
//    {
//        if(name == "苹果")
//            return std::make_shared<Apple>();
//        else
//            return std::make_shared<Banana>();
//    }
//};

// 工厂方法模式
// 每一个具体类都有自己工厂
// class Factory
//{
// public:
//    virtual std::shared_ptr<Fruit> create() = 0;
//};
//
// class AppleFactory : public Factory
//{
// public:
//    std::shared_ptr<Fruit> create() override
//    {
//        return std::make_shared<Apple>();
//    }
//};
//
// class BananaFactory : public Factory
//{
// public:
//    std::shared_ptr<Fruit> create() override
//    {
//        return std::make_shared<Banana>();
//    }
//};

// 抽象工厂模式
// 设计思路1，由一个工厂生成两个不同产品
//class Factory
//{
//public:
//    virtual std::shared_ptr<Fruit> fruitFactory(const std::string &name) = 0;
//    virtual std::shared_ptr<Animal> animalFactory(const std::string &name) = 0;
//};
//
//class FruitFactory : public Factory
//{
//public:
//    std::shared_ptr<Fruit> fruitFactory(const std::string &name) override
//    {
//        if (name == "苹果")
//            return std::make_shared<Apple>();
//        else
//            return std::make_shared<Banana>();
//    }
//
//    std::shared_ptr<Animal> animalFactory(const std::string &name) override
//    {
//        return nullptr;
//        //return std::make_shared<Animal>();
//    }
//};
//
//class AnimalFactory : public Factory
//{
//public:
//    std::shared_ptr<Animal> animalFactory(const std::string &name) override
//    {
//        if (name == "小狗")
//            return std::make_shared<Dog>();
//        else
//            return std::make_shared<Cat>();
//    }
//
//    std::shared_ptr<Fruit> fruitFactory(const std::string &name) override
//    {
//        return nullptr;
//        //return std::make_shared<Fruit>();
//    }
//};
//
//class FactorProducer
//{
//public:
//    static std::shared_ptr<Factory> createFactory(const std::string &type)
//    {
//        if(type == "水果")
//        {
//            std::cout << "创建一个水果工厂" << std::endl;
//            return std::make_shared<FruitFactory>();
//        }
//        else
//        {
//            std::cout << "创建一个动物工厂" << std::endl;
//            return std::make_shared<AnimalFactory>();
//        }
//    }
//};

// 抽象工厂模式
// 分离工厂接口
class FruitFactory
{
public:
    virtual std::shared_ptr<Fruit> createFruit(const std::string &name) = 0;
};

class AnimalFactory
{
public:
    virtual std::shared_ptr<Animal> createAnimal(const std::string &name) = 0;
};

class ConcreteFruitFactory : public FruitFactory
{
public:
    std::shared_ptr<Fruit> createFruit(const std::string &name) override
    {
        if(name == "苹果")
            return std::make_shared<Apple>();
        else if(name == "香蕉")
            return std::make_shared<Banana>();
        else
            return nullptr;
    }
};

class ConcreteAnimalFactroy : public AnimalFactory
{
public:
    std::shared_ptr<Animal> createAnimal(const std::string &name) override
    {
        if(name == "小狗")
            return std::make_shared<Dog>();
        else if(name == "小猫")
            return std::make_shared<Cat>();
        else
            return nullptr;
    }
};

class FactoryProducer
{
public:
    static std::shared_ptr<FruitFactory> FruitProducer()
    {
        return std::make_shared<ConcreteFruitFactory>();
    }
    static std::shared_ptr<AnimalFactory> AnimalProducer()
    {
        return std::make_shared<ConcreteAnimalFactroy>();
    }
};

int main()
{
    // 简单工厂模式
    // std::shared_ptr<Fruit> fruit = Factory::create("苹果");
    // fruit->name();
    // fruit = Factory::create("香蕉");
    // fruit->name();

    // 工厂方法模式
    // std::shared_ptr<Factory> fac(new AppleFactory);
    // std::shared_ptr<Fruit> fruit = fac->create();
    // fruit->name();
    // fac.reset(new BananaFactory);
    // fruit = fac->create();
    // fruit->name();

    // 抽象工厂模式
    // 1.先生产一个具体的工厂
    //std::shared_ptr<Factory> factory = FactorProducer::createFactory("水果");

    //// 2.使用具体的工厂，生成该工厂中的类别
    //std::shared_ptr<Fruit> fruit = factory->fruitFactory("苹果");
    //fruit->name();
    //fruit = factory->fruitFactory("香蕉");
    //fruit->name();

    FactoryProducer::FruitProducer()->createFruit("苹果")->name();
    FactoryProducer::AnimalProducer()->createAnimal("小狗")->name();
    return 0;
}